﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading.Tasks;

namespace MyHome.Server.PluginBase
{
    /// <summary>
    /// Abstract base class for all output plugins providing some generic implementation.
    /// </summary>
    /// <typeparam name="T">The type of data generated from this plugin</typeparam>
    public abstract class OutputPlugin<T> : Plugin, IOutputPlugin<T>
    {
        /// <summary>
        /// Gets the type of the plugin.
        /// </summary>
        /// <value>
        /// <see cref="PluginType.Output"/>
        /// </value>
        public override PluginType PluginType
        {
            get { return PluginType.Output; }
        }

        /// <summary>
        /// Sends the output asynchronous.
        /// </summary>
        /// <param name="value">The value of data to output.</param>
        /// <returns>A value indicating the success of this operation.</returns>
        public async Task<bool> SendOutputAsync(T value)
        {
            try
            {
                await Task.Run(() => OnSendOutput(value));
                Trace.TraceInformation("{0} \"{1}\", Id: {2} sent new output: {3}", PluginType.ToString(), this, Id, value);
                return true;
            }
            catch
            {
                Trace.TraceError("{0} \"{1}\", Id: {2} failed to sent new output: {3}", PluginType.ToString(), this, Id, value);
                State = PluginState.Error;
                return false;
            }
        }

        /// <summary>
        /// Called when data to output is received.
        /// </summary>
        /// <param name="value">The value to output.</param>
        protected abstract void OnSendOutput(T value);
    }
}